package video.background.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import video.background.Controller.ControllerParams.ViewShowCreateTeam;
import video.background.Controller.View.SelfInTeamView;
import video.background.Controller.View.TeamView;
import video.background.Dao.*;
import video.background.Model.*;
import video.background.Utils.*;
import video.background.Utils.VoiceUtils.CreateGroup;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/teamInfomation")
@CrossOrigin(origins = "*", maxAge = 3600)
@Api(tags = "团队信息管理相关接口")
public class TeamInfomationController {
    @Autowired
    private TeamDao teamDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserGroupDao userGroupDao;

    @Autowired
    private NoticeDao noticeDao;

    @Autowired
    private VoiceLibraryDao voiceLibraryDao;

    @Autowired
    private OptRecodeDao optRecodeDao;

    private static String requestUrl = "https://api.xf-yun.com/v1/private/s782b4996";
    private static String APPID = "5b1c8319";
    private static String apiSecret = "OTNhYjQ1MzMwYmVhNmQwNTJlMTBiMzFk";
    private static String apiKey = "cace5423224c609f5fdfbdbf72fa2dac";

    @GetMapping("/selectTeam")
    @ApiOperation("展示团队信息")
    public Result selectTeam(Long groupId){
        Team team = teamDao.selectById(groupId);
        if(team == null) return Result.Error("团队信息未找到！",null);
        TeamView teamView = new TeamView();
        BeanUtils.copyProperties(team,teamView);
        //获取创始人姓名
        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getGroupId,groupId).eq(UserGroup::getUserRole,'0');
        UserGroup userGroup = userGroupDao.selectOne(uglqw);
        Long userId = userGroup.getUserId();
        Users users = userDao.selectById(userId);
        teamView.setFoundName(users.getUserName());
        return Result.Success("请求成功",teamView);
    }

    @PostMapping("/updateTeam")
    @ApiOperation("修改团队信息")
    public Result updateTeam(@RequestHeader String Authorization,@RequestBody Team newteam){
        //解析token
        if(Authorization == null || Authorization.equals(""))
            return Result.Error("申请人数据不全，请检查数据",null);
        Long userId = JwtUtils.decoderToken(Authorization);

        if(userId == null)
            return Result.Error("申请人数据不全，请检查数据",null);
        if(newteam.getGroupId() == null) return Result.Error("未找到团队，请检查数据~",null);
        //查找原数据所在位置
        LambdaQueryWrapper<UserGroup> ulqw = new LambdaQueryWrapper<>();
        ulqw.eq(UserGroup::getUserId,userId).eq(UserGroup::getGroupId,newteam.getGroupId());
        UserGroup userGroup = userGroupDao.selectOne(ulqw);  //找到该用户
        LambdaQueryWrapper<Team> ulqw1 = new LambdaQueryWrapper<>();
        ulqw1.eq(Team::getGroupId,userGroup.getGroupId());
        Team oldTeam = teamDao.selectOne(ulqw1);  //找到该团队
        //如果权限有效，则修改
        if(userGroup.getUserRole() == '1' || userGroup.getUserRole() == '0'){
            oldTeam.setGroupName(newteam.getGroupName());
            oldTeam.setSlogan(newteam.getSlogan());
            oldTeam.setGroupAvatar(newteam.getGroupAvatar());
            userGroupDao.updateById(userGroup);
            teamDao.updateById(oldTeam);
            MessageUtils.sendMessage(userId,userDao.selectById(userId).getUserName(),4, Long.valueOf(userGroup.getGroupId()));
            return Result.Success("修改成功",null);
        }
        return Result.Error("权限不够，请检查数据",null);
    }

    @PostMapping("/deleteTeam")
    @ApiOperation("注销团队信息")
    public Result deleteTeam(@RequestHeader String Authorization,@RequestBody Map<String, Long>data){
        Long groupId = data.get("groupId");
//        System.out.println("注销团队信息时的groupid: " + groupId);
        if (groupId == 0) return Result.Error("团队名为空，请检查数据",null);
        //解析token
        Long userId = JwtUtils.decoderToken(Authorization);
        if(userId == null) return Result.Error("信息不全!", null);

        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getUserId,userId).eq(UserGroup::getGroupId,groupId);
        UserGroup userGroup = userGroupDao.selectOne(uglqw);
        if(userGroup == null) return Result.Error("未查询到团队信息!", null);
        if(userGroup.getUserRole() != '0') return Result.Error("权限不足!", null);

        // 删除成员信息表
        LambdaQueryWrapper<UserGroup> uglqw1 = new LambdaQueryWrapper<>();
        uglqw1.eq(UserGroup::getGroupId,groupId);
        List<UserGroup> userGroups = userGroupDao.selectList(uglqw1);
        for(UserGroup item : userGroups){
            userGroupDao.deleteById(item.getId());
        }
        // 删除通知表信息
        LambdaQueryWrapper<Notice> nlqw = new LambdaQueryWrapper<>();
        nlqw.eq(Notice::getGroupId, groupId);
        List<Notice> notices = noticeDao.selectList(nlqw);
        for (Notice notice : notices){
            noticeDao.deleteById(notice.getNoticeId());
        }
        MessageUtils.sendMessage(userId,userDao.selectById(userId).getUserName(),1,groupId);
        // 删除group信息
        teamDao.deleteById(groupId);
        return Result.Success("注销团队成功！", null);
    }


    @GetMapping("/showJoinTeam")
    @ApiOperation("展示我加入的团队列表")
    public Result showJoinTeam(@RequestHeader String Authorization,
                               @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                               @RequestParam(name = "pageSize", required = false, defaultValue = "10") Long pageSize){
        Long userId = JwtUtils.decoderToken(Authorization);
        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getUserId, userId);
        List<TeamView> teamViews = userGroupDao.selectList(uglqw).stream().map(userGroup -> {
            String groupId = userGroup.getGroupId();
            Team team = teamDao.selectById(groupId);
            if (team != null) {
                TeamView teamView = new TeamView();
                BeanUtils.copyProperties(team, teamView);
                // 创始人的账号可能已经注销
                LambdaQueryWrapper<UserGroup> uglqw1 = new LambdaQueryWrapper<>();
                uglqw1.eq(UserGroup::getGroupId, groupId).eq(UserGroup::getUserRole, '0');
                UserGroup found = userGroupDao.selectOne(uglqw1);
                teamView.setFoundName(found == null ? "用户已注销" : userDao.selectById(found.getUserId()).getUserName());
                return teamView;
            }
            return null;
        }).collect(Collectors.toList());
        int count = teamViews.size();
        Page<TeamView> teamViewPage = new Page<>(currentPage, pageSize);
        teamViewPage.setRecords(teamViews);
        teamViewPage.setTotal(count);
        teamViewPage.setPages(count % pageSize == 0 ? count / pageSize : count / pageSize + 1);
        return Result.Success("请求成功！", teamViewPage);
    }

    @GetMapping("/showCreateTeam")
    @ApiOperation("展示我创建的团队列表")
    public Result showCreateTeam(@RequestHeader String Authorization,
                                 @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                                 @RequestParam(name = "pageSize", required = false, defaultValue = "10") Long pageSize){
        ArrayList<TeamView> teamViews = new ArrayList<>();
        Page<TeamView> teamPage = new Page<>(currentPage, pageSize);

        //解析token
        if(Authorization == null || Authorization.equals(""))
            return Result.Error("申请人数据不全，请检查数据",null);
        Long userId = JwtUtils.decoderToken(Authorization);
        if(userId == null)
            return Result.Error("申请人数据不全，请检查数据",null);
        LambdaQueryWrapper<Users> users_ulqw = new LambdaQueryWrapper<>();
        users_ulqw.eq(Users::getUserId,userId);
        Users users = userDao.selectOne(users_ulqw);
        //向前端返回的数据
        ViewShowCreateTeam data = new ViewShowCreateTeam();
        data.setTeamPage(teamPage);
        data.setBuildTeam(users.getBuildTeam());

        LambdaQueryWrapper<UserGroup> UsersGroup_ulqw = new LambdaQueryWrapper<>();
        UsersGroup_ulqw.eq(UserGroup::getUserId,userId).eq(UserGroup::getUserRole,'0');
        List<UserGroup> userGroup = userGroupDao.selectList(UsersGroup_ulqw);  //找到所在的团队
        if (userGroup.size() == 0) return Result.Success("未找到您所在团队，请检查数据",data);
        for (UserGroup group : userGroup){
            Team team = teamDao.selectById(group.getGroupId());
            if (team == null) continue;
            TeamView teamView = new TeamView();
            BeanUtils.copyProperties(team,teamView);
            teamView.setFoundName(users.getUserName());
            teamViews.add(teamView);
        }
        int count = teamViews.size();
        teamPage.setTotal(count);
        teamPage.setPages(count % pageSize == 0 ? count / pageSize : count / pageSize + 1);
        teamPage.setRecords(teamViews);
        return Result.Success("请求成功", data);
    }


    @ApiOperation("查看团队邀请码")
    @GetMapping("/searchAccessCode")
    public Result searchAccessCode(@RequestHeader String Authorization,@RequestParam String groupId){
        //解析token
        if(Authorization == null || Authorization.equals("") || groupId == null)
            return Result.Error("申请人数据不全",null);
        Long userId = JwtUtils.decoderToken(Authorization);
        if (userId == null) return Result.Error("申请人数据不全",null);
        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getGroupId,groupId).eq(UserGroup::getUserId,userId);
        UserGroup userGroup = userGroupDao.selectOne(uglqw);
        if (userGroup == null ) return Result.Error("您不在该团队，请检查数据~",null);
        if (userGroup.getUserRole() == '0' || userGroup.getUserRole() == '1'){
            //查询邀请码
            Team team = teamDao.selectById(groupId);
            return Result.Success("查询成功！",team.getAccessCode());
        }
        return Result.Error("没有权限查询邀请码",null);
    }

    @PostMapping("/addTeam")
    @ApiOperation("创建团队")
    public Result addTeam(@RequestHeader String Authorization,@RequestBody Team data){
        //解析token
        if(Authorization == null || Authorization.equals(""))
            return Result.Error("申请人数据不全，请检查数据",null);
        Long userId = JwtUtils.decoderToken(Authorization);
        if(userId == null)
            return Result.Error("申请人数据不全，请检查数据",null);
        LambdaQueryWrapper<Users> users_ulqw = new LambdaQueryWrapper<>();
        users_ulqw.eq(Users::getUserId,userId);
        Users users = userDao.selectOne(users_ulqw);
        if(data.getGroupName() == null || data.getGroupName().equals("")){
            return Result.Error("数据不全！", null);
        }
        //判断创建团队数量是否小于5
        LambdaQueryWrapper<UserGroup> userGroup_ulqw = new LambdaQueryWrapper<>();
        userGroup_ulqw.eq(UserGroup::getUserId,userId);
        if(users.getBuildTeam() == 0) return Result.Success("您的团队创建数量已经到达最大值，无法进行创建",null);
        int cnt = users.getBuildTeam() - 1;
        users.setBuildTeam(cnt);
        userDao.updateById(users);
        //设置默认slogan
        if(data.getSlogan() == null || data.getSlogan().equals("")) data.setSlogan("此群主很懒，什么都没有留下~");
        //设置创建团队的属性
        Team team = new Team();
        BeanUtils.copyProperties(data,team);
        team.setRegisterTime(DateTimeUtils.dateTimeToString());
        team.setAccessCode(generateUniqueAccessCode());
        team.setCurrentMemberSize(0l);
        team.setCurrentFileSize(0.);
        team.setCapacity(10);   //默认为10
        team.setFileCapacity(40);
        UserGroup userGroup = new UserGroup();
        //插入团队信息
        teamDao.insert(team);
        //编辑UserGroup
        userGroup.setUserId(userId);
        userGroup.setUserRole('0');
        userGroup.setGroupId(team.getGroupId().toString());
        userGroup.setIsAccess(1);
        userGroup.setIsInputVoice('0');
        userGroupDao.insert(userGroup);
        // 创建团队时自动创建声纹库
        String libId = generateUniqueLibId();
        Map<String, Object> result = CreateGroup.doCreateGroup(requestUrl, APPID, apiSecret, apiKey, libId);
        VoiceLibrary voiceLibrary = new VoiceLibrary();
        voiceLibrary.setLibId(libId);
        voiceLibrary.setCreateTime(DateTimeUtils.dateTimeToString());
        voiceLibrary.setUpdateTime(DateTimeUtils.dateTimeToString());
        voiceLibrary.setGroupId(team.getGroupId());
        voiceLibraryDao.insert(voiceLibrary);
        //记录日志
        char userRole = userGroup.getUserRole();
        String role = "";
        if (userRole == '0') role = "创始人";
        else if (userRole == '1') role = "管理者";
        else role = "普通成员";
        OptRecode optRecode = new OptRecode(null,team.getGroupId(),team.getGroupName(),userId,users.getUserName(),0,"创建声纹库",
                DateTimeUtils.localDateTimeAndSecondToString(),userRole,role);
        optRecodeDao.insert(optRecode);
        MessageUtils.sendMessage(userId,users.getUserName(),0,team.getGroupId());
        return Result.Success("创建成功",null);
    }

    @ApiOperation("管理员上传团队头像的接口")
    @PostMapping("/uploadGroupAvatar")
    public Result uploadGroupAvatar(@RequestHeader String Authorization,
                                    @RequestParam("file")MultipartFile file,
                                    @RequestParam Long groupId){
        Long userId = JwtUtils.decoderToken(Authorization);
        if(userId == null) return Result.Error("数据不全！", null);
        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getGroupId, groupId).eq(UserGroup::getUserId, userId);
        if(userGroupDao.selectOne(uglqw).getUserRole() == '2') return Result.Error("权限不足！", null);
        try {
            String fileName = groupId.toString() + ".png";
            String link = TencentCOSUtil.uploadfileFromBin("GroupAvatar", fileName, file);
            // 将数据信息保存在数据库
            Team team = teamDao.selectById(groupId);
            team.setGroupAvatar(link);
            teamDao.updateById(team);
            return Result.Success("上传成功！",link);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.Error500("上传失败！",null);
        }
    }

    @GetMapping("/getMySelfInTeam")
    @ApiOperation("用户查询自己在团队内的信息")
    public Result getMySelfInTeam(@RequestHeader String Authorization, @RequestParam Long groupId){
        Long userId = JwtUtils.decoderToken(Authorization);
        if(userId == null || groupId == 0) return Result.Error("数据不全！", null);
        Users users = userDao.selectById(userId);
        if(users == null) return Result.Error("未查询到您的用户信息！", null);
        LambdaQueryWrapper<UserGroup> uglqw = new LambdaQueryWrapper<>();
        uglqw.eq(UserGroup::getUserId,userId).eq(UserGroup::getGroupId,groupId);
        UserGroup userGroup = userGroupDao.selectOne(uglqw);
        char userRole = userGroup.getUserRole();
        String roleName = null;
        if(userRole == '0') roleName = "创始人";
        else if(userRole == '1') roleName = "管理员";
        else roleName = "成员";
        SelfInTeamView selfInTeamView = new SelfInTeamView(userId, users.getUserName(), userGroup.getUserRole(),
                roleName, users.getUserAvatar(), users.getUserIntroduction());
        return Result.Success("请求成功！", selfInTeamView);
    }

    /* 相关工具 */
    private String generateUniqueLibId(){
        while(true){
            String s1 = Random.generateString(10);
            String s2 = Random.generateString(5);
            if(!judgeLibIdUnique(s1 + "_" + s2)){
                if(judgeLibIdUnique(s2 + "_" + s1)){
                    return s2 + "_" + s1;
                }
            }else{
                return s1 + "_" + s2;
            }
        }
    }
    private boolean judgeLibIdUnique(String libId){
        VoiceLibrary voiceLibrary = voiceLibraryDao.selectById(libId);
        return voiceLibrary == null;
    }
    private String generateUniqueAccessCode(){
        while(true){
            String accessCode = Random.generateString(8);
            if(judgeAccessCodeUnique(accessCode)){
                return accessCode;
            }
        }
    }
    private boolean judgeAccessCodeUnique(String accessCode) {
        LambdaQueryWrapper<Team> tlqw = new LambdaQueryWrapper<>();
        tlqw.eq(Team::getAccessCode, accessCode);
        return teamDao.selectList(tlqw).isEmpty();
    }
}
